#include <QGraphicsView>
#include <QRectF>
#include <QMenuBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QToolBox>
#include <QFileDialog>
#include <QListWidget>
#include <QPushButton>
#include <QMessageBox>

#include "mainwindow.h"
#include "newmapdialog.h"
#include "addlayerdialog.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ready = false;
    changed = false;

    createMenus();
    setWidgets();
    //selectLayer(0);

    ready = true;
}

void MainWindow::createMenus()
{
    fileMenu = new QMenu("File", this);
    fileMenu = this->menuBar()->addMenu("File");

    fileNewAction = new QAction("New...", this);
    fileMenu->addAction(fileNewAction);

    fileExportAction = new QAction("Export...", this);
    fileMenu->addAction(fileExportAction);

    connect(fileNewAction, SIGNAL(triggered()), this, SLOT(onFileNewClicked()));
    connect(fileExportAction, SIGNAL(triggered()), this, SLOT(onFileExportClicked()));
}

void MainWindow::setWidgets()
{
    QWidget *centralWidget = new QWidget;

    layout = new QHBoxLayout;
    toolBox = new QToolBox;
    toolBox->setMinimumWidth(256);
    toolBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);

    addToolBoxStuff();

    layout->addWidget(toolBox);

    scene = new TileDesignerScene(this);

    view = new QGraphicsView(scene);
    view->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    layout->addWidget(view);

    centralWidget->setLayout(layout);
    setCentralWidget(centralWidget);
}

void MainWindow::addToolBoxStuff()
{
    selectScene = new TileSelectScene;
    selectView = new QGraphicsView(selectScene);
    selectView->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    connect(selectScene, SIGNAL(selectedTileChanged(qint32)), this, SLOT(onSelectedTileChanged(qint32)));

    toolBox->addItem(selectView, tr("Tiles"));

    layersWidget = new QWidget;

    layout1 = new QVBoxLayout;
    layout2 = new QHBoxLayout;
    layersList = new QListWidget;
    layout1->addWidget(layersList);

    connect(layersList, SIGNAL(currentRowChanged(int)), this, SLOT(onLayersListCurrentRowChanged(int)));
    connect(layersList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onLayersListItemChanged(QListWidgetItem*)));

    /*backgroundItem = new QListWidgetItem(tr("Background"), layersList);
    backgroundItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    backgroundItem->setCheckState(Qt::Checked);*/

    addLayer = new QPushButton("Add");
    deleteLayer = new QPushButton("Delete");

    connect(addLayer, SIGNAL(clicked()), this, SLOT(onAddLayerClicked()));
    connect(deleteLayer, SIGNAL(clicked()), this, SLOT(onDeleteLayerClicked()));

    layout2->addWidget(addLayer);
    layout2->addSpacing(100);
    layout2->addWidget(deleteLayer);

    layout1->addLayout(layout2);
    layersWidget->setLayout(layout1);

    toolBox->addItem(layersWidget, tr("Layers"));
}

void MainWindow::selectLayer(qint16 id)
{
    layersList->setCurrentRow(id);
}

void MainWindow::onLayersListCurrentRowChanged(int)
{
    scene->setCurrentLayer(layersList->currentRow() + 1);
}

void MainWindow::onFileNewClicked()
{
    if (!changed || (changed &&
        QMessageBox::question(this, tr("Lose changes?"), tr("Lose changes?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes))
    {
        NewMapDialog dialogue(this);
        if (dialogue.exec() == QDialog::Accepted)
        {
           selectScene->load(dialogue.getTileSetPath(),
                             dialogue.getTileSizeX(),
                             dialogue.getTileSizeY());

           scene->create(*dialogue.getColour(),
                         dialogue.getTileSizeX(),
                         dialogue.getTileSizeY(),
                         dialogue.getMapSizeX(),
                         dialogue.getMapSizeY(),
                         dialogue.getTileSetPath());
       
            backgroundItem = new QListWidgetItem(tr("Background"), layersList);
            backgroundItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
            backgroundItem->setCheckState(Qt::Checked);

            selectLayer(0);

            changed = true;
        }
    }
}

void MainWindow::onFileExportClicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, "Export map", "", "Images (*.png *.jpg)");

    if (fileName != "")
    {
        QImage img = scene->save();
        img.save(fileName);
    }
}

void MainWindow::onSelectedTileChanged(qint32 tileNum)
{
   scene->setSelectedTile(tileNum);
}

void MainWindow::onAddLayerClicked()
{
    AddLayerDialog dialogue;
    if (dialogue.exec() == QDialog::Accepted)
    {
        QListWidgetItem *item = new QListWidgetItem(dialogue.getLayerName(), layersList);
        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
        item->setCheckState(Qt::Checked);

        scene->addLayer(dialogue.getLayerName());
        selectLayer(layersList->count() - 1);
    }
}

void MainWindow::onDeleteLayerClicked()
{
    if (layersList->selectedItems().count() > 0
        && layersList->selectedItems()[0] != backgroundItem)
    {
        QListWidgetItem *item = layersList->takeItem(layersList->currentRow());
        if (item != 0) delete item;
    }
}

void MainWindow::onLayersListItemChanged(QListWidgetItem* item)
{
    if (ready)
    {
        scene->setLayerVisible(layersList->row(item) + 1, (item->checkState() == Qt::Checked));
    }
}

MainWindow::~MainWindow()
{
    delete layout;
    delete fileMenu;
    delete fileNewAction;
    delete fileExportAction;
    delete scene;
    delete view;
    delete layersWidget;
    delete layersList;
    delete addLayer;
    delete deleteLayer;
    delete backgroundItem;
    delete toolBox;
    delete layout1;
    delete layout2;
}
